/**
 *逐个加载函数 
 */
package utils.core
{
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;

	public class OneByOneLoader
	{
		private var _loader:Loader;
		private static var instance:OneByOneLoader;
		
		private var _forEachFun:Function;//每个资源加载完成时执行的函数
		private var _loadFailFun:Function;
		private var _urls:Array;
		private var _loadedNum:uint = 0;
		private var _total:uint = 0;
		private var _loadContext:LoaderContext;
		
		public function OneByOneLoader()
		{
			_loader =  new Loader();
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoad);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loadFail);
		}
		
		public static function getDefault():OneByOneLoader
		{
			if(!instance)
				instance = new OneByOneLoader();
			return instance;
		}
		
		/**
		 *逐个加载 urls中的资源
		 * @param urls：资源系列
		 * @param forEachFun：对每个完成加载的资源执行的函数，形如：forEachFun(loader:Loader, index:uint)
		 * @param loadFailFun：加载某个资源错误时执行的函数，形如：loadFailFun(loader:Loader)
		 * 
		 */		
		public function load(urls:Array, forEachFun:Function=null, loadFailFun:Function=null, loadContext:LoaderContext=null):void
		{
			if((!urls) || (urls.length == 0))
				return;
			if(_loadedNum != 0)
			{
				trace("上一次的加载任务未完成")
				return;
			}
			_forEachFun = forEachFun;
			_loadFailFun = loadFailFun;
			_urls = urls;
			if(loadContext != null)
				_loadContext = loadContext;
			else
			{
				var _loadContext:LoaderContext = new LoaderContext();
				_loadContext.applicationDomain = flash.system.ApplicationDomain.currentDomain;
			}
				
			_total = urls.length;
			_loadedNum = 0;
			_loader.load(new URLRequest(urls[_loadedNum]), _loadContext);
		}
		
		private function onLoad(evt:Event):void
		{
			if(_forEachFun != null)
			{
				if(_loadContext)//如果_loadContext被赋非空值，回调函数必须接收context类型的参数
					_forEachFun((evt.currentTarget as LoaderInfo).loader, _loadedNum, _loadContext);
				else
					_forEachFun((evt.currentTarget as LoaderInfo).loader, _loadedNum);
			}
				
			_loadedNum++;
			if(!loaded)
				_loader.load(new URLRequest(_urls[_loadedNum]),_loadContext);
			else
			{
				_forEachFun = null;
				_loadFailFun = null;
			}
		}
		
		private function loadFail(evt:IOErrorEvent):void
		{
			if(_loadFailFun != null)
				_loadFailFun(evt.currentTarget as Loader);
			trace(evt.text);
			_loadedNum++;
			if(!loaded)
				_loader.load(new URLRequest(_urls[_loadedNum]),_loadContext);
			else
			{
				_forEachFun = null;
				_loadFailFun = null;
			}
		}
		
		public function get loaded():Boolean
		{
			return (_loadedNum == _total);
		}
	}
}